<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Ruby syntax</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Ruby_syntax"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Ruby_syntax rootpage-Ruby_syntax skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Ruby syntax</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1305433154">
/* start https://en.wikipedia.org/ */
.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style>
<p>The syntax of the <a href="Ruby_programming_language" class="mw-redirect" title="Ruby programming language">Ruby programming language</a> is broadly similar to that of <a href="Perl" title="Perl">Perl</a> and <a href="Python_(programming_language)" title="Python (programming language)">Python</a>. Class and method definitions are signaled by keywords, whereas code blocks can be defined by either keywords or braces. In contrast to Perl, variables are not obligatorily prefixed with a <a href="Sigil_(computer_programming)" title="Sigil (computer programming)">sigil</a>. When used, the sigil changes the semantics of scope of the variable. For practical purposes there is no distinction between <a href="Expression_(programming)" class="mw-redirect" title="Expression (programming)">expressions</a> and <a href="Statement_(programming)" class="mw-redirect" title="Statement (programming)">statements</a>.<sup id="cite_ref-while_1-0" class="reference"><a href="#cite_note-while-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-precedence_2-0" class="reference"><a href="#cite_note-precedence-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup> Line breaks are significant and taken as the end of a statement; a semicolon may be equivalently used. Unlike Python, indentation is not significant.
</p><p>One of the differences from Python and Perl is that Ruby keeps all of its instance variables completely private to the class and only exposes them through accessor methods (<code>attr_writer</code>, <code>attr_reader</code>, etc.). Unlike the "getter" and "setter" methods of other languages like <a href="C%2B%2B" title="C++">C++</a> or <a href="Java_(programming_language)" title="Java (programming language)">Java</a>, accessor methods in Ruby can be created with a single line of code via <a href="Metaprogramming" title="Metaprogramming">metaprogramming</a>; however, accessor methods can also be created in the traditional fashion of C++ and Java. As invocation of these methods does not require the use of parentheses, it is trivial to change an instance variable into a full function without modifying a single line of calling code or having to do any refactoring achieving similar functionality to <a href="C_Sharp_(programming_language)" title="C Sharp (programming language)">C#</a> and <a href="VB.NET" class="mw-redirect" title="VB.NET">VB.NET</a> property members.
</p><p>Python's property descriptors are similar, but come with a trade-off in the development process. If one begins in Python by using a publicly exposed instance variable, and later changes the implementation to use a private instance variable exposed through a property descriptor, code internal to the class may need to be adjusted to use the private variable rather than the public property. Ruby's design forces all instance variables to be private, but also provides a simple way to declare <code>set</code> and <code>get</code> methods. This is in keeping with the idea that in Ruby one never directly accesses the internal members of a class from outside the class; rather, one passes a message to the class and receives a response.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Interactive_sessions">Interactive sessions</h2></div>
<p>The following examples can be run in a Ruby shell such as <a href="Interactive_Ruby_Shell" class="mw-redirect" title="Interactive Ruby Shell">Interactive Ruby Shell</a>, or saved in a file and run from the command line by typing <code>ruby <i><filename></i></code>.
</p><p>Classic <a href="%22Hello%2C_World!%22_program" title=""Hello, World!" program">Hello world</a> example:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="nb">puts</span><span class="w"> </span><span class="s1">'Hello World!'</span>
</pre></div>
<p>Some basic Ruby code:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="c1"># Everything, including a literal, is an object, so this works:</span>
<span class="o">-</span><span class="mi">199</span><span class="o">.</span><span class="n">abs</span><span class="w"> </span><span class="c1"># => 199</span>
<span class="s1">'ice is nice'</span><span class="o">.</span><span class="n">length</span><span class="w"> </span><span class="c1"># => 11</span>
<span class="s1">'ruby is cool.'</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">'u'</span><span class="p">)</span><span class="w"> </span><span class="c1"># => 1</span>
<span class="s2">"Nice Day Isn't It?"</span><span class="o">.</span><span class="n">downcase</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span><span class="o">.</span><span class="n">uniq</span><span class="o">.</span><span class="n">sort</span><span class="o">.</span><span class="n">join</span>
<span class="c1"># => " '?acdeinsty"</span>
</pre></div>
<p>Input:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="nb">print</span><span class="w"> </span><span class="s1">'Please type name >'</span>
<span class="nb">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">gets</span><span class="o">.</span><span class="n">chomp</span>
<span class="nb">puts</span><span class="w"> </span><span class="s2">"Hello </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">."</span>
</pre></div>
<p>Conversions:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="nb">puts</span><span class="w"> </span><span class="s1">'Give me a number'</span>
<span class="n">number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">gets</span><span class="o">.</span><span class="n">chomp</span>
<span class="nb">puts</span><span class="w"> </span><span class="n">number</span><span class="o">.</span><span class="n">to_i</span>
<span class="n">output_number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">number</span><span class="o">.</span><span class="n">to_i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span>
<span class="nb">puts</span><span class="w"> </span><span class="n">output_number</span><span class="o">.</span><span class="n">to_s</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">' is a bigger number.'</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Strings">Strings</h2></div>
<p>There are a variety of ways to define strings in Ruby.
</p><p>The following assignments are equivalent:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="se">\n</span><span class="s2">This is a double-quoted string</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%Q{</span><span class="se">\n</span><span class="sx">This is a double-quoted string</span><span class="se">\n</span><span class="sx">}</span>
<span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%{</span><span class="se">\n</span><span class="sx">This is a double-quoted string</span><span class="se">\n</span><span class="sx">}</span>
<span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%/\nThis is a double-quoted string\n/</span>
<span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o"><<-</span><span class="dl">BLOCK</span>
<span class="sh">This is a double-quoted string</span>
<span class="dl">BLOCK</span>
</pre></div>
<p>Strings support <a href="Variable_interpolation" class="mw-redirect" title="Variable interpolation">variable interpolation</a>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="n">var</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="o">.</span><span class="mi">14159</span>
<span class="s2">"pi is </span><span class="si">#{</span><span class="n">var</span><span class="si">}</span><span class="s2">"</span>
<span class="o">=></span><span class="w"> </span><span class="s2">"pi is 3.14159"</span>
</pre></div>
<p>The following assignments are equivalent and produce <a href="Raw_string" class="mw-redirect" title="Raw string">raw strings</a>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'This is a single-quoted string'</span>
<span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%q{This is a single-quoted string}</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Collections">Collections</h2></div>
<p>Constructing and using an <a href="Array_data_type" class="mw-redirect" title="Array data type">array</a>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">[</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="s1">'hello'</span><span class="p">,</span><span class="w"> </span><span class="mi">14</span><span class="o">.</span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="mi">6</span><span class="p">,</span><span class="w"> </span><span class="mi">15</span><span class="o">]]</span>
<span class="n">a</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="c1"># => 14.5</span>
<span class="n">a</span><span class="o">.</span><span class="n n-Operator">[]</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="c1"># => 14.5</span>
<span class="n">a</span><span class="o">.</span><span class="n">reverse</span><span class="w"> </span><span class="c1"># => [[6, 15], 2, 1, 14.5, 'hello', 3]</span>
<span class="n">a</span><span class="o">.</span><span class="n">flatten</span><span class="o">.</span><span class="n">uniq</span><span class="w"> </span><span class="c1"># => [3, 'hello', 14.5, 1, 2, 6, 15]</span>
</pre></div>
<p>Constructing and using an <a href="Associative_array" title="Associative array">associative array</a> (in Ruby, called a <i>hash</i>):
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="nb">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">Hash</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="c1"># equivalent to hash = {}</span>
<span class="nb">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="ss">water</span><span class="p">:</span><span class="w"> </span><span class="s1">'wet'</span><span class="p">,</span><span class="w"> </span><span class="ss">fire</span><span class="p">:</span><span class="w"> </span><span class="s1">'hot'</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1"># makes the previous line redundant as we are now</span>
<span class="w"> </span><span class="c1"># assigning hash to a new, separate hash object</span>
<span class="nb">puts</span><span class="w"> </span><span class="nb">hash</span><span class="o">[</span><span class="ss">:fire</span><span class="o">]</span><span class="w"> </span><span class="c1"># prints "hot"</span>
<span class="nb">hash</span><span class="o">.</span><span class="n">each_pair</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">value</span><span class="o">|</span><span class="w"> </span><span class="c1"># or: hash.each do |key, value|</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"</span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2"> is </span><span class="si">#{</span><span class="n">value</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="c1"># returns {:water=>"wet", :fire=>"hot"} and prints:</span>
<span class="c1"># water is wet</span>
<span class="c1"># fire is hot</span>
<span class="nb">hash</span><span class="o">.</span><span class="n">delete</span><span class="w"> </span><span class="ss">:water</span><span class="w"> </span><span class="c1"># deletes the pair :water => 'wet' and returns "wet"</span>
<span class="nb">hash</span><span class="o">.</span><span class="n">delete_if</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">key</span><span class="p">,</span><span class="n">value</span><span class="o">|</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">'hot'</span><span class="p">}</span><span class="w"> </span><span class="c1"># deletes the pair :fire => 'hot' and returns {}</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Control_structures">Control structures</h2></div>
<p>If statement:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="c1"># Generate a random number and print whether it's even or odd.</span>
<span class="k">if</span><span class="w"> </span><span class="nb">rand</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span><span class="o">.</span><span class="n">even?</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"It's even"</span>
<span class="k">else</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"It's odd"</span>
<span class="k">end</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Blocks_and_iterators">Blocks and iterators</h2></div>
<p>The two syntaxes for creating a code block:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="p">{</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s1">'Hello, World!'</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1"># note the braces</span>
<span class="c1"># or:</span>
<span class="k">do</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s1">'Hello, World!'</span>
<span class="k">end</span>
</pre></div>
<p>A code block can be passed to a method as an optional block argument. Many built-in methods have such arguments:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">'file.txt'</span><span class="p">,</span><span class="w"> </span><span class="s1">'w'</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">file</span><span class="o">|</span><span class="w"> </span><span class="c1"># 'w' denotes "write mode"</span>
<span class="w"> </span><span class="n">file</span><span class="o">.</span><span class="n">puts</span><span class="w"> </span><span class="s1">'Wrote some text.'</span>
<span class="k">end</span><span class="w"> </span><span class="c1"># file is automatically closed here</span>
<span class="no">File</span><span class="o">.</span><span class="n">readlines</span><span class="p">(</span><span class="s1">'file.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">each</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">line</span><span class="o">|</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">line</span>
<span class="k">end</span>
<span class="c1"># => Wrote some text.</span>
</pre></div>
<p>Parameter-passing a block to be a <a href="Closure_(computer_science)" class="mw-redirect" title="Closure (computer science)">closure</a>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="c1"># In an object instance variable (denoted with '@'), remember a block.</span>
<span class="k">def</span><span class="w"> </span><span class="nf">remember</span><span class="p">(</span><span class="o">&</span><span class="n">a_block</span><span class="p">)</span>
<span class="w"> </span><span class="vi">@block</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a_block</span>
<span class="k">end</span>
<span class="c1"># Invoke the preceding method, giving it a block that takes a name.</span>
<span class="n">remember</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="nb">name</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"Hello, </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">!"</span><span class="p">}</span>
<span class="c1"># Call the closure (note that this happens not to close over any free variables):</span>
<span class="vi">@block</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="s1">'Jon'</span><span class="p">)</span><span class="w"> </span><span class="c1"># => "Hello, Jon!"</span>
</pre></div>
<p>Creating an <a href="Anonymous_function" title="Anonymous function">anonymous function</a>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="nb">proc</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">arg</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">arg</span><span class="p">}</span>
<span class="no">Proc</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">arg</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">arg</span><span class="p">}</span>
<span class="nb">lambda</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">arg</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">arg</span><span class="p">}</span>
<span class="o">-></span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="nb">puts</span><span class="w"> </span><span class="n">arg</span><span class="p">}</span><span class="w"> </span><span class="c1"># introduced in Ruby 1.9</span>
</pre></div>
<p>Returning <a href="Closure_(computer_science)" class="mw-redirect" title="Closure (computer science)">closures</a> from a method:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">def</span><span class="w"> </span><span class="nf">create_set_and_get</span><span class="p">(</span><span class="n">initial_value</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="c1"># note the default value of 0</span>
<span class="w"> </span><span class="n">closure_value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">initial_value</span>
<span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="no">Proc</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">closure_value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">},</span><span class="w"> </span><span class="no">Proc</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">closure_value</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">]</span>
<span class="k">end</span>
<span class="n">setter</span><span class="p">,</span><span class="w"> </span><span class="n">getter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">create_set_and_get</span><span class="w"> </span><span class="c1"># returns two values</span>
<span class="n">setter</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="mi">21</span><span class="p">)</span>
<span class="n">getter</span><span class="o">.</span><span class="n">call</span><span class="w"> </span><span class="c1"># => 21</span>
<span class="c1"># Parameter variables can also be used as a binding for the closure,</span>
<span class="c1"># so the preceding can be rewritten as:</span>
<span class="k">def</span><span class="w"> </span><span class="nf">create_set_and_get</span><span class="p">(</span><span class="n">closure_value</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="nb">proc</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">closure_value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">,</span><span class="w"> </span><span class="nb">proc</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">closure_value</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">]</span>
<span class="k">end</span>
</pre></div>
<p>Yielding the flow of program control to a block that was provided at calling time:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">def</span><span class="w"> </span><span class="nf">use_hello</span>
<span class="w"> </span><span class="k">yield</span><span class="w"> </span><span class="s2">"hello"</span>
<span class="k">end</span>
<span class="c1"># Invoke the preceding method, passing it a block.</span>
<span class="n">use_hello</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">string</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">string</span><span class="p">}</span><span class="w"> </span><span class="c1"># => 'hello'</span>
</pre></div>
<p>Iterating over enumerations and arrays using blocks:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s1">'hi'</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="o">.</span><span class="mi">14</span><span class="o">]</span>
<span class="n">array</span><span class="o">.</span><span class="n">each</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">item</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">item</span><span class="w"> </span><span class="p">}</span>
<span class="c1"># prints:</span>
<span class="c1"># 1</span>
<span class="c1"># 'hi'</span>
<span class="c1"># 3.14</span>
<span class="n">array</span><span class="o">.</span><span class="n">each_index</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">index</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"</span><span class="si">#{</span><span class="n">index</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">array</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span><span class="w"> </span><span class="p">}</span>
<span class="c1"># prints:</span>
<span class="c1"># 0: 1</span>
<span class="c1"># 1: 'hi'</span>
<span class="c1"># 2: 3.14</span>
<span class="c1"># The following uses a (a..b) Range</span>
<span class="p">(</span><span class="mi">3</span><span class="o">..</span><span class="mi">6</span><span class="p">)</span><span class="o">.</span><span class="n">each</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">num</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="p">}</span>
<span class="c1"># prints:</span>
<span class="c1"># 3</span>
<span class="c1"># 4</span>
<span class="c1"># 5</span>
<span class="c1"># 6</span>
<span class="c1"># The following uses a (a...b) Range</span>
<span class="p">(</span><span class="mi">3</span><span class="o">...</span><span class="mi">6</span><span class="p">)</span><span class="o">.</span><span class="n">each</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">num</span><span class="o">|</span><span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="p">}</span>
<span class="c1"># prints:</span>
<span class="c1"># 3</span>
<span class="c1"># 4</span>
<span class="c1"># 5</span>
</pre></div>
<p>A method such as <code>inject</code> can accept both a parameter and a block. The <code>inject</code> method iterates over each member of a list, performing some function on it while retaining an aggregate. This is analogous to the <code><a href="Foldl" class="mw-redirect" title="Foldl">foldl</a></code> function in <a href="Functional_programming_languages" class="mw-redirect" title="Functional programming languages">functional programming languages</a>. For example:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="o">].</span><span class="n">inject</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">sum</span><span class="p">,</span><span class="w"> </span><span class="n">element</span><span class="o">|</span><span class="w"> </span><span class="n">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">element</span><span class="p">}</span><span class="w"> </span><span class="c1"># => 19</span>
</pre></div>
<p>On the first pass, the block receives 10 (the argument to inject) as <code>sum</code>, and 1 (the first element of the array) as <code>element</code>. This returns 11, which then becomes <code>sum</code> on the next pass. It is added to 3 to get 14, which is then added to 5 on the third pass, to finally return 19.
</p><p>Using an enumeration and a block to square the numbers 1 to 10 (using a <i>range</i>):
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="n">collect</span><span class="w"> </span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="p">}</span><span class="w"> </span><span class="c1"># => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]</span>
</pre></div>
<p>Or invoke a method on each item (<code>map</code> is a synonym for <code>collect</code>):
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:to_f</span><span class="p">)</span><span class="w"> </span><span class="c1"># => [1.0, 2.0, 3.0, 4.0, 5.0]</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Classes">Classes</h2></div>
<p>The following code defines a class named <code>Person</code>. In addition to <code>initialize</code>, the usual constructor to create new objects, it has two methods: one to override the <code><=></code> comparison operator (so <code>Array#sort</code> can sort by age) and the other to override the <code>to_s</code> method (so <code>Kernel#puts</code> can format its output). Here, <code>attr_reader</code> is an example of metaprogramming in Ruby: <code>attr_accessor</code> defines getter and setter methods of instance variables, but <code>attr_reader</code> only getter methods. The last evaluated statement in a method is its return value, allowing the omission of an explicit <code>return</code> statement.
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">class</span><span class="w"> </span><span class="nc">Person</span>
<span class="w"> </span><span class="kp">attr_reader</span><span class="w"> </span><span class="ss">:name</span><span class="p">,</span><span class="w"> </span><span class="ss">:age</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span><span class="p">)</span>
<span class="w"> </span><span class="vi">@name</span><span class="p">,</span><span class="w"> </span><span class="vi">@age</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf"><=></span><span class="p">(</span><span class="n">person</span><span class="p">)</span><span class="w"> </span><span class="c1"># the comparison operator for sorting</span>
<span class="w"> </span><span class="vi">@age</span><span class="w"> </span><span class="o"><=></span><span class="w"> </span><span class="n">person</span><span class="o">.</span><span class="n">age</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">to_s</span>
<span class="w"> </span><span class="s2">"</span><span class="si">#{</span><span class="vi">@name</span><span class="si">}</span><span class="s2"> (</span><span class="si">#{</span><span class="vi">@age</span><span class="si">}</span><span class="s2">)"</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
<span class="n">group</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">[</span>
<span class="w"> </span><span class="no">Person</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Bob"</span><span class="p">,</span><span class="w"> </span><span class="mi">33</span><span class="p">),</span>
<span class="w"> </span><span class="no">Person</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Chris"</span><span class="p">,</span><span class="w"> </span><span class="mi">16</span><span class="p">),</span>
<span class="w"> </span><span class="no">Person</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Ash"</span><span class="p">,</span><span class="w"> </span><span class="mi">23</span><span class="p">)</span>
<span class="o">]</span>
<span class="nb">puts</span><span class="w"> </span><span class="n">group</span><span class="o">.</span><span class="n">sort</span><span class="o">.</span><span class="n">reverse</span>
</pre></div>
<p>The preceding code prints three names in reverse age order:
</p>
<div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre>Bob (33)
Ash (23)
Chris (16)
</pre></div>
<p><code>Person</code> is a constant and is a reference to a <code>Class</code> object.
</p>
<div class="mw-heading mw-heading3"><h3 id="Open_classes">Open classes</h3></div>
<p>In Ruby, classes are never closed: methods can always be added to an existing class. This applies to <i>all</i> classes, including the standard, built-in classes. All that is needed to do is open up a class definition for an existing class, and the new contents specified will be added to the existing contents. A simple example of adding a new method to the standard library's <code>Time</code> class:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="c1"># re-open Ruby's Time class</span>
<span class="k">class</span><span class="w"> </span><span class="nc">Time</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">yesterday</span>
<span class="w"> </span><span class="nb">self</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">86400</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
<span class="n">today</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="w"> </span><span class="c1"># => 2013-09-03 16:09:37 +0300</span>
<span class="n">yesterday</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">today</span><span class="o">.</span><span class="n">yesterday</span><span class="w"> </span><span class="c1"># => 2013-09-02 16:09:37 +0300</span>
</pre></div>
<p>Adding methods to previously defined classes is often called <a href="Monkey_patch" title="Monkey patch">monkey-patching</a>. If performed recklessly, the practice can lead to both behavior collisions with subsequent unexpected results and code scalability problems.
</p><p>Since Ruby 2.0 it has been possible to use <a rel="nofollow" class="external text" href="http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/">refinements</a> to reduce the potentially negative consequences of monkey-patching, by limiting the scope of the patch to particular areas of the code base.
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="c1"># re-open Ruby's Time class</span>
<span class="k">module</span><span class="w"> </span><span class="nn">RelativeTimeExtensions</span>
<span class="w"> </span><span class="n">refine</span><span class="w"> </span><span class="no">Time</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">half_a_day_ago</span>
<span class="w"> </span><span class="nb">self</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">43200</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span><span class="w"> </span><span class="nn">MyModule</span>
<span class="w"> </span><span class="k">class</span><span class="w"> </span><span class="nc">MyClass</span>
<span class="w"> </span><span class="c1"># Allow the refinement to be used</span>
<span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="no">RelativeTimeExtensions</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">window</span>
<span class="w"> </span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="o">.</span><span class="n">half_a_day_ago</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Exceptions">Exceptions</h2></div>
<p>An exception is raised with a <code>raise</code> call:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">raise</span>
</pre></div>
<p>An optional message can be added to the exception:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">raise</span><span class="w"> </span><span class="s2">"This is a message"</span>
</pre></div>
<p>Exceptions can also be specified by the programmer:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">raise</span><span class="w"> </span><span class="no">ArgumentError</span><span class="p">,</span><span class="w"> </span><span class="s2">"Illegal arguments!"</span>
</pre></div>
<p>Alternatively, an exception instance can be passed to the <code>raise</code> method:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">raise</span><span class="w"> </span><span class="no">ArgumentError</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Illegal arguments!"</span><span class="p">)</span>
</pre></div>
<p>This last construct is useful when raising an instance of a custom exception class featuring a constructor that takes more than one argument:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">class</span><span class="w"> </span><span class="nc">ParseError</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="no">Exception</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">initialize</span><span class="p">(</span><span class="n">input</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="n">pos</span><span class="p">)</span>
<span class="w"> </span><span class="k">super</span><span class="w"> </span><span class="s2">"Could not parse '</span><span class="si">#{</span><span class="n">input</span><span class="si">}</span><span class="s2">' at line </span><span class="si">#{</span><span class="n">line</span><span class="si">}</span><span class="s2">, position </span><span class="si">#{</span><span class="n">pos</span><span class="si">}</span><span class="s2">"</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
<span class="k">raise</span><span class="w"> </span><span class="no">ParseError</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Foo"</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">9</span><span class="p">)</span>
</pre></div>
<p>Exceptions are handled by the <code>rescue</code> clause. Such a clause can catch exceptions that inherit from <code>StandardError</code>. Other flow control keywords that can be used when handling exceptions are <code>else</code> and <code>ensure</code>:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">begin</span>
<span class="w"> </span><span class="c1"># do something</span>
<span class="k">rescue</span>
<span class="w"> </span><span class="c1"># handle exception</span>
<span class="k">else</span>
<span class="w"> </span><span class="c1"># do this if no exception was raised</span>
<span class="k">ensure</span>
<span class="w"> </span><span class="c1"># do this whether or not an exception was raised</span>
<span class="k">end</span>
</pre></div>
<p>It is a common mistake to attempt to catch all exceptions with a simple rescue clause. To catch all exceptions one must write:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">begin</span>
<span class="w"> </span><span class="c1"># do something</span>
<span class="k">rescue</span><span class="w"> </span><span class="no">Exception</span>
<span class="w"> </span><span class="c1"># Exception handling code here.</span>
<span class="w"> </span><span class="c1"># Don't write only "rescue"; that only catches StandardError, a subclass of Exception.</span>
<span class="k">end</span>
</pre></div>
<p>Or catch particular exceptions:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">begin</span>
<span class="w"> </span><span class="c1"># do something</span>
<span class="k">rescue</span><span class="w"> </span><span class="no">RuntimeError</span>
<span class="w"> </span><span class="c1"># handle only RuntimeError and its subclasses</span>
<span class="k">end</span>
</pre></div>
<p>It is also possible to specify that the exception object be made available to the handler clause:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">begin</span>
<span class="w"> </span><span class="c1"># do something</span>
<span class="k">rescue</span><span class="w"> </span><span class="no">RuntimeError</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="c1"># handling, possibly involving e, such as "puts e.to_s"</span>
<span class="k">end</span>
</pre></div>
<p>Alternatively, the most recent exception is stored in the magic global <code>$!</code>.
</p><p>Several exceptions can also be caught:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="k">begin</span>
<span class="w"> </span><span class="c1"># do something</span>
<span class="k">rescue</span><span class="w"> </span><span class="no">RuntimeError</span><span class="p">,</span><span class="w"> </span><span class="no">Timeout</span><span class="o">::</span><span class="no">Error</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="c1"># handling, possibly involving e</span>
<span class="k">end</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Metaprogramming">Metaprogramming</h2></div>
<p>Ruby code can programmatically modify, at <a href="Run_time_(program_lifecycle_phase)" class="mw-redirect" title="Run time (program lifecycle phase)">runtime</a>, aspects of its own structure that would be fixed in more rigid languages, such as class and method definitions. This sort of <a href="Metaprogramming" title="Metaprogramming">metaprogramming</a> can be used to write more concise code and effectively extend the language.
</p><p>For example, the following Ruby code generates new methods for the built-in <code>String</code> class, based on a list of colors. The methods wrap the contents of the string with an HTML tag styled with the respective color.
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="no">COLORS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="ss">black</span><span class="p">:</span><span class="w"> </span><span class="s2">"000"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">red</span><span class="p">:</span><span class="w"> </span><span class="s2">"f00"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">green</span><span class="p">:</span><span class="w"> </span><span class="s2">"0f0"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">yellow</span><span class="p">:</span><span class="w"> </span><span class="s2">"ff0"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">blue</span><span class="p">:</span><span class="w"> </span><span class="s2">"00f"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">magenta</span><span class="p">:</span><span class="w"> </span><span class="s2">"f0f"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">cyan</span><span class="p">:</span><span class="w"> </span><span class="s2">"0ff"</span><span class="p">,</span>
<span class="w"> </span><span class="ss">white</span><span class="p">:</span><span class="w"> </span><span class="s2">"fff"</span><span class="w"> </span><span class="p">}</span>
<span class="k">class</span><span class="w"> </span><span class="nc">String</span>
<span class="w"> </span><span class="no">COLORS</span><span class="o">.</span><span class="n">each</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">color</span><span class="p">,</span><span class="n">code</span><span class="o">|</span>
<span class="w"> </span><span class="n">define_method</span><span class="w"> </span><span class="s2">"in_</span><span class="si">#{</span><span class="n">color</span><span class="si">}</span><span class="s2">"</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="s2">"<span style=</span><span class="se">\"</span><span class="s2">color: #</span><span class="si">#{</span><span class="n">code</span><span class="si">}</span><span class="se">\"</span><span class="s2">></span><span class="si">#{</span><span class="nb">self</span><span class="si">}</span><span class="s2"></span>"</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>The generated methods could then be used like this:
</p>
<div class="mw-highlight mw-highlight-lang-ruby mw-content-ltr" dir="ltr"><pre><span class="s2">"Hello, World!"</span><span class="o">.</span><span class="n">in_blue</span>
<span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="s2">"<span style=</span><span class="se">\"</span><span class="s2">color: #00f</span><span class="se">\"</span><span class="s2">>Hello, World!</span>"</span>
</pre></div>
<p>To implement the equivalent in many other languages, the programmer would have to write each method (<code>in_black</code>, <code>in_red</code>, <code>in_green</code>, etc.) separately.
</p><p>Some other possible uses for Ruby metaprogramming include:
</p>
<ul><li>intercepting and modifying method calls</li>
<li>implementing new inheritance models</li>
<li>dynamically generating classes from parameters</li>
<li>automatic object serialization</li>
<li>interactive help and debugging</li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */
.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}
/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-while-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-while_1-0">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}
/* end https://en.wikipedia.org/ */
</style><cite class="citation web cs1"><a rel="nofollow" class="external text" href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/1120">"[ruby-talk:01120] Re: The value of while..."</a> <q>In Ruby's syntax, statement is just a special case of an expression that cannot appear as an argument (e.g. multiple assignment).</q></cite></span>
</li>
<li id="cite_note-precedence-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-precedence_2-0">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/2460">"[ruby-talk:02460] Re: Precedence question"</a>. <q>statement [...] can not be part of expression unless grouped within parentheses.</q></cite></span>
</li>
</ol></div></div></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-01-03" href="https://en.wikipedia.org/wiki/?title=Ruby_syntax&oldid=1267073271">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>